//******************************************************************************
//this code is protected by the GNU affero GPLv3
//author:Sylvain BERTRAND <sylvain.bertrand AT gmail dot com>
//                        <digital.ragnarok AT gmail dot com>
//******************************************************************************
#define REGISTRY_C
#include "globals.h"
#undef REGISTRY_C

void registry_publish(s32 name)
{
  s32 c=0;
  while(1){
    if(c==CLIENTS_MAX) break;
    if(clients[c].so != 1) client_registry_publish(&clients[c],name);
    ++c;
  }
}

void registry_unpublish(s32 name)
{
  s32 c=0;
  while(1){
    if(c==CLIENTS_MAX) break;
    if(clients[c].so != 1) client_registry_unpublish(&clients[c],name);
    ++c;
  }
}

void registry_gbl_ref(struct gbl *g)
{
  if(g->is_singleton) return;
  ++g->n;
}

s32 registry_gbl_unref(struct gbl *g)
{
  if(g->is_singleton) return 1;
  if(g->n!=0&&--g->n) return g->n;
  g->release(g);
  return 0;
}

void registry_gbl_generic_release(struct gbl *g)
{
  g->itf=WL_INVALID;
}

s8 registry_send(struct client *c,u32 id)
{
  s8 r=registry_map_new_visible(c,REGISTRY_NAME,id);
  if(r==LWL_ERR) goto exit;

  //only objects after the registry get published to clients
  s32 name=REGISTRY_NAME+1;
  while(1){
    if(name==REGISTRY_N_MAX) break;
    if(registry[name].itf!=WL_INVALID){
      r=wl_registry_ev_global(c,id,name);
      if(r==LWL_ERR) goto exit;
    }
    ++name;
  }

exit:
  return r;
}

s8 registry_bind(struct client *c,s32 name,u32 id)
{
  s8 r;
  if(name>=REGISTRY_N_MAX){
    PERR("client(%d):registry:bind name %d out of range\n",c->so,name);
    r=LWL_ERR;goto exit;
  }

  r=registry_map_new_visible(c,name,id);
  if(r==LWL_ERR) goto exit;

  //binding is done then call the bind post method if any
  if(registry[name].bind_post) r=registry[name].bind_post(c,name,id);

exit:
  return r;
}

void registry_init(void)
{
  memset(&registry[0],0,sizeof(registry));

  //our server singletons
  registry[DISPLAY_NAME].itf=WL_DISPLAY;
  registry[DISPLAY_NAME].is_singleton=1;
  registry[REGISTRY_NAME].itf=WL_REGISTRY;
  registry[REGISTRY_NAME].is_singleton=1;
  registry[SHM_NAME].itf=WL_SHM;
  registry[SHM_NAME].is_singleton=1;
  registry[SHM_NAME].bind_post=shm_bind_post;
  registry[COMPOSITOR_NAME].itf=WL_COMPOSITOR;
  registry[COMPOSITOR_NAME].is_singleton=1;
  registry[DATA_DEVICE_MANAGER_NAME].itf=WL_DATA_DEVICE_MANAGER;
  registry[DATA_DEVICE_MANAGER_NAME].is_singleton=1;
  registry[SHELL_NAME].itf=WL_SHELL;
  registry[SHELL_NAME].is_singleton=1;
  registry[DEFAULT_SEAT_NAME].itf=WL_SEAT;
  registry[DEFAULT_SEAT_NAME].is_singleton=1;
  registry[DEFAULT_SEAT_NAME].bind_post=seat_bind_post;
  memcpy(&registry[DEFAULT_SEAT_NAME].seat.id[0],FREEDESKTOP_DEFAULT_SEAT_ID,
                                           sizeof(FREEDESKTOP_DEFAULT_SEAT_ID));
  s32 j=DEFAULT_SEAT_NAME+1;
  while(1){
    if(j==REGISTRY_N_MAX) break;
    registry[j].itf=WL_INVALID;
    ++j;
  }
}
